#ifndef WIDGET_PLAY_H
#define WIDGET_PLAY_H



#include "gui.h"
#include "game.h"
#include "units.h"



class unit;
class bonus;

class game_state;

class pre_move_info;
class pre_fire_info;




/** @brief Class representating normal game square in play widget
*
*   \image html widget_play.jpeg
*/
class map_square: public QGraphicsPixmapItem
{

public:

	/** @brief Constructor sets square to accept hover events
	*	@param parent Qt parent
	*	@param scene Qt scene, where the pixmap is
	*/
	map_square( QGraphicsItem* parent = 0, QGraphicsScene* scene = 0 );


protected:

	/**	@brief Qt mouse press event
	*	right click	-> move there with selected unit
	*	left click	-> unselect selected unit
	*	@param event for resolving pressed button
	*/
	void mousePressEvent( QGraphicsSceneMouseEvent* event );
	/**	@brief Qt mouse press event
	*	shows path and cost of movement if movement is possible
	*	@param event not used
	*/
	void hoverEnterEvent( QGraphicsSceneHoverEvent* event );
	/**	@brief Qt hover leave event
	*	deletes showed path
	*	@param event not used
	*/
	void hoverLeaveEvent( QGraphicsSceneHoverEvent* event );

};



/** @brief Class representating bonus in play widget
*
*   \image html widget_play.jpeg
*/
class map_bonus: public QGraphicsPixmapItem
{

public:

	/** @brief Constructor loads proper pixmap for the bonus
	*	@param b bonus represented by the pixmap, constraint: b != 0
	*	@param parent Qt parent
	*	@param scene Qt scene, where the pixmap is
	*/
	map_bonus( bonus* b, QGraphicsItem* parent = 0, QGraphicsScene* scene = 0 );


private:

	//! bonus represented by the pixmap
	bonus* bon;

};



/** @brief Class representating unit in play widget
*
*   \image html widget_play.jpeg
*/
class map_unit:public QGraphicsPixmapItem
{

public:

	/** @brief Constructor loads proper pixmaps and sounds for the unit and sets it to accept hover events
	*	@param un unit, constraint: un != 0
	*	@param parent Qt parent
	*	@param scene Qt scene, where the pixmap is
	*/
	map_unit( unit* un, QGraphicsItem* parent = 0, QGraphicsScene* scene = 0 );

	//! @brief Unselects selected unit and selects this
	void select();
	//! @brief Unselects unit and updates all relevant labels
	void unselect();
	/** @brief Sets pixmaps
	*	@param n normal pixmap
	*	@param s selected pixmap
	*/
	void setPixmaps( QPixmap* n, QPixmap* s );
	//! @brief Sets normal pixmap as current pixmap
	void setNormalPixmap();
	//! @brief Sets selected pixmap as current pixmap
	void setSelectedPixmap();
	/**	@brief Sets fire sound
	*	@param s fire sound
	*/
	void setFireSound( QSound* s );
	//! @brief Plays fire sound
	void playFireSound();
	/**	@brief Sets unit's info - for destruction purposes
	*	@param ui info label to be set
	*/
	void setUnitInfo( QLabel* ui )
	{
		uinfo = ui;
	};

	//! unit
	unit* u;
	//! unit's info
	QLabel* uinfo;


protected:

	/**	@brief Qt mouse press event
	*	right click	-> attack this unit
	*	left click	-> select this unit
	*	@param event for resolving pressed button
	*/
	void mousePressEvent( QGraphicsSceneMouseEvent* event );
	/**	@brief Qt mouse press event
	*	shows fire line if fire is possible
	*	@param event not used
	*/
	void hoverEnterEvent( QGraphicsSceneHoverEvent* event );
	/**	@brief Qt hover leave event
	*	deletes showed fire line
	*	@param event not used
	*/
	void hoverLeaveEvent( QGraphicsSceneHoverEvent* event );


private:

	//! pixmap for normal state
	QPixmap* normal_pixmap;
	//! pixmap for selected state
	QPixmap* selected_pixmap;
	//! fire sound
	QSound* fire_sound;

};



/** @brief Class representating a path
*
*   \image html widget_play.jpeg
*/
class p
{

public:

	/** @brief Createch queue of pixmaps and optionaly shows cost of movement at the end
	*	@param pth queue of coordinates pair, that represent the path
	*	@param cost cost of the movement, if cost == 0, cost label is not shown
	*/
	p( queue< pair< unsigned int, unsigned int > >* pth, unsigned int cost );
	//! @brief Deletes pixmaps from queue
	~p();


private:

	//! queue of pixmaps representating the path
	queue< QGraphicsPixmapItem* > s;
	//! label that shows cost of the movement
	QGraphicsTextItem* cost_l;
	//! whether show cost, or not
	bool cost_set;

};



/** @brief Main gui widget for playing part of the game.
*
*	Left click on map_unit will select the unit, left click somewhere else will unselect selected unit.
*	When current player's unit is selected, than hover events on map_square will show path with cost to move there if the movement is possible.
*	When current player's unit is selected, then right click on map_unit will generate ATT command and forward it to game.
*	When current player's unit is selected, then right click on map_square will generate MOV command and forward it to game.
*
*   \image html widget_play.jpeg
*/
class play_widget: public QWidget
{

	Q_OBJECT

public:

	/** @brief Creates part of the gui
	*	@param parent Qt parent
	*	@param flags Qt flags
	*/
	play_widget( QWidget* parent = 0, Qt::WindowFlags flags = 0 );
	//! deletes map array
	~play_widget();

	/** @brief Forwards command to main engine
	*	@param plr player, that sends the command
	*	@param cmd sent command
	*/
	void forward_command( player* plr, const string& cmd )
	{
		emit send_command( plr, cmd );
	};

	//! @brief Generates map terrain
	void create_map();
	//! @brief Adds bonuses to he map
	void add_bonuses();
	//! @brief Adds player's units to the map and units survey
	void add_players();
	//! @brief updates label showing current player's name
	void update_curr_player_label();
	//! @brief updates label showing remaining time
	void update_curr_time_label();
	/** @brief Updates label showing information of the unit
	*	@param u unit, which information is being updated
	*	@param ul label containing the information
	*/
	void update_unit_status( unit* u, QLabel* ul );
	/** @brief Updates information about selected unit
	*	@param u selected unit
	*/
	void update_selected_unit_status( unit* u );
	//! @brief Forces labels update
	void update_labels();

	/** @brief Shows move event
	*	@param u moving unit
	*	@param x x coordinate, where it moves, constraint: x < map->size_x
	*	@param y y coordinate, where it moves, constraint: y < map->size_y
	*	@param pmi some aditional information needed for visualising the event
	*/
	void show_move( unit* u, unsigned int x, unsigned int y, pre_move_info* pmi );
	/** @brief Shows fire event
	*	@param u attacking unit
	*	@param x x coordinate, where it attacks, constraint: x < map->size_x
	*	@param y y coordinate, where it attacks, constraint: y < map->size_y
	*	@param pfi some aditional information needed for visualising the event
	*/
	void show_fire( unit* u, unsigned int x, unsigned int y, pre_fire_info* pfi );
	//! @brief Shows nex turn event - updates all relevant labels
	void show_next_turn();
	/** @brief Shows pause event 
	*	@param paused true if pause, false if continue
	*/
	void set_paused( bool paused );

	


	//! widget's layout
	QVBoxLayout* layout;

	//! label showing information about selected unit
	QLabel* selected_unit_status_l;

	//! label showing current player's name
	QLabel* current_player_l;
	//! label showing current player's remaining time
	QLabel* current_time_l;


	//! game map
	QGraphicsScene* gs;
	//! currently selected unit
	map_unit* selected_unit;
	//! 2D array of map_squares representating map terrain
	array2d< map_square* >* map_array;
	//! shown path
	p* path;
	//!shown remote path - from ai or network player
	p* remote_path;
	//! shown fire line
	QGraphicsLineItem* fire_line;
	//! shown remote fire line - from ai or network player
	QGraphicsLineItem* remote_fire_line;

	//! button NEXT
	QPushButton* next_b;
	//! button for obtaining nex command from AI player
	QPushButton* next_ai_command_b;
	//! button for pausing AI player
	QPushButton* pause_b;


signals:

	//! @brief Qt singnal that sends commands to game core
	void send_command( player*, const string& );


protected slots:

	//! @brief Qt slot, that deletes remote path - called with some delay
	void delete_remote_path();
	//! @brief Qt slot, that deletes remote fire line - called with some delay
	void delete_remote_fire_line();
	//! @brief Qt slot, that shows estimated_def_places computed with ai_support_computations
	void show_estimated_places();
	//! @brief Qt slot, that shows dangerous_places computed with ai_support_computations
	void show_dangerous_places();
	//! @brief Qt slot, that shows dangerous_places_nobody computed with ai_support_computations
	void show_dangerous_places_nobody();
	//! @brief Qt slot, that shows attackable_places computed with ai_support_computations
	void show_attackable_places();
	//! @brief Qt slot, that shows range_places computed with ai_support_computations
	void show_range_places();
	//! @brief Qt slot, that shows game_state_score computed with ai_support_computations
	void show_game_state_score();
	//! @brief Qt slot, that ends current turn
	void next();
	//! @brief Qt slot, that forces AI player to send next command
	void next_ai_command();
	//! @brief Qt slot, that pauses AI player
	void ai_pause();
	//! @brief Qt slot, that saves position of all objects to a file
	void save_game();


private:

	/** @brief	Visualises 2D array of integers
	*	@param	map array to visualise
	*	@return generated widget
	*/
	QWidget* create_map_widget( array2d< unsigned int >* map );

};



#endif